home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2005 October / PCWOCT05.iso / Software / FromTheMag / XAMPP 1.4.14 / xampp-win32-1.4.14-installer.exe / xampp / php / pear / DB / sqlite.php < prev    next >
PHP Script  |  2004-10-01  |  22KB  |  696 lines

  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */
  3. // +----------------------------------------------------------------------+
  4. // | PHP Version 4                                                        |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1997-2004 The PHP Group                                |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 2.02 of the PHP license,      |
  9. // | that is bundled with this package in the file LICENSE, and is        |
  10. // | available at through the world-wide-web at                           |
  11. // | http://www.php.net/license/2_02.txt.                                 |
  12. // | If you did not receive a copy of the PHP license and are unable to   |
  13. // | obtain it through the world-wide-web, please send a note to          |
  14. // | license@php.net so we can mail you a copy immediately.               |
  15. // +----------------------------------------------------------------------+
  16. // | Authors: Urs Gehrig <urs@circle.ch>                                  |
  17. // |          Mika Tuupola <tuupola@appelsiini.net>                       |
  18. // | Maintainer: Daniel Convissor <danielc@php.net>                       |
  19. // +----------------------------------------------------------------------+
  20. //
  21. // $Id: sqlite.php,v 1.66 2004/04/28 20:13:10 danielc Exp $
  22.  
  23. require_once 'DB/common.php';
  24.  
  25. /**
  26.  * Database independent query interface definition for the SQLite
  27.  * PECL extension.
  28.  *
  29.  * @package  DB
  30.  * @version  $Id: sqlite.php,v 1.66 2004/04/28 20:13:10 danielc Exp $
  31.  * @category Database
  32.  * @author   Urs Gehrig <urs@circle.ch>
  33.  * @author   Mika Tuupola <tuupola@appelsiini.net>
  34.  */
  35. class DB_sqlite extends DB_common
  36. {
  37.     // {{{ properties
  38.  
  39.     var $connection;
  40.     var $phptype, $dbsyntax;
  41.     var $prepare_tokens = array();
  42.     var $prepare_types = array();
  43.     var $_lasterror = '';
  44.  
  45.     // }}}
  46.     // {{{ constructor
  47.  
  48.     /**
  49.      * Constructor for this class.
  50.      *
  51.      * Error codes according to sqlite_exec.  Error Codes specification is
  52.      * in the {@link http://sqlite.org/c_interface.html online manual}.
  53.      *
  54.      * This errorhandling based on sqlite_exec is not yet implemented.
  55.      *
  56.      * @access public
  57.      */
  58.     function DB_sqlite()
  59.     {
  60.  
  61.         $this->DB_common();
  62.         $this->phptype = 'sqlite';
  63.         $this->dbsyntax = 'sqlite';
  64.         $this->features = array (
  65.             'prepare' => false,
  66.             'pconnect' => true,
  67.             'transactions' => false,
  68.             'limit' => 'alter'
  69.         );
  70.  
  71.         // SQLite data types, http://www.sqlite.org/datatypes.html
  72.         $this->keywords = array (
  73.             'BLOB'      => '',
  74.             'BOOLEAN'   => '',
  75.             'CHARACTER' => '',
  76.             'CLOB'      => '',
  77.             'FLOAT'     => '',
  78.             'INTEGER'   => '',
  79.             'KEY'       => '',
  80.             'NATIONAL'  => '',
  81.             'NUMERIC'   => '',
  82.             'NVARCHAR'  => '',
  83.             'PRIMARY'   => '',
  84.             'TEXT'      => '',
  85.             'TIMESTAMP' => '',
  86.             'UNIQUE'    => '',
  87.             'VARCHAR'   => '',
  88.             'VARYING'   => ''
  89.         );
  90.         $this->errorcode_map = array(
  91.         );
  92.     }
  93.  
  94.     // }}}
  95.     // {{{ connect()
  96.  
  97.     /**
  98.      * Connect to a database represented by a file.
  99.      *
  100.      * @param $dsn the data source name; the file is taken as
  101.      *        database; "sqlite://root:@host/test.db?mode=0644"
  102.      * @param $persistent (optional) whether the connection should
  103.      *        be persistent
  104.      * @access public
  105.      * @return int DB_OK on success, a DB error on failure
  106.      */
  107.     function connect($dsninfo, $persistent = false)
  108.     {
  109.         if (!DB::assertExtension('sqlite')) {
  110.             return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
  111.         }
  112.  
  113.         $this->dsn = $dsninfo;
  114.  
  115.         if ($dsninfo['database']) {
  116.             if (!file_exists($dsninfo['database'])) {
  117.                 if (!touch($dsninfo['database'])) {
  118.                     return $this->sqliteRaiseError(DB_ERROR_NOT_FOUND);
  119.                 }
  120.                 if (!isset($dsninfo['mode']) ||
  121.                     !is_numeric($dsninfo['mode']))
  122.                 {
  123.                     $mode = 0644;
  124.                 } else {
  125.                     $mode = octdec($dsninfo['mode']);
  126.                 }
  127.                 if (!chmod($dsninfo['database'], $mode)) {
  128.                     return $this->sqliteRaiseError(DB_ERROR_NOT_FOUND);
  129.                 }
  130.                 if (!file_exists($dsninfo['database'])) {
  131.                     return $this->sqliteRaiseError(DB_ERROR_NOT_FOUND);
  132.                 }
  133.             }
  134.             if (!is_file($dsninfo['database'])) {
  135.                 return $this->sqliteRaiseError(DB_ERROR_INVALID);
  136.             }
  137.             if (!is_readable($dsninfo['database'])) {
  138.                 return $this->sqliteRaiseError(DB_ERROR_ACCESS_VIOLATION);
  139.             }
  140.         } else {
  141.             return $this->sqliteRaiseError(DB_ERROR_ACCESS_VIOLATION);
  142.         }
  143.  
  144.         $connect_function = $persistent ? 'sqlite_popen' : 'sqlite_open';
  145.         if (!($conn = @$connect_function($dsninfo['database']))) {
  146.             return $this->sqliteRaiseError(DB_ERROR_NODBSELECTED);
  147.         }
  148.         $this->connection = $conn;
  149.  
  150.         return DB_OK;
  151.     }
  152.  
  153.     // }}}
  154.     // {{{ disconnect()
  155.  
  156.     /**
  157.      * Log out and disconnect from the database.
  158.      *
  159.      * @access public
  160.      * @return bool true on success, false if not connected.
  161.      * @todo fix return values
  162.      */
  163.     function disconnect()
  164.     {
  165.         $ret = @sqlite_close($this->connection);
  166.         $this->connection = null;
  167.         return $ret;
  168.     }
  169.  
  170.     // }}}
  171.     // {{{ simpleQuery()
  172.  
  173.     /**
  174.      * Send a query to SQLite and returns the results as a SQLite resource
  175.      * identifier.
  176.      *
  177.      * @param the SQL query
  178.      * @access public
  179.      * @return mixed returns a valid SQLite result for successful SELECT
  180.      * queries, DB_OK for other successful queries. A DB error is
  181.      * returned on failure.
  182.      */
  183.     function simpleQuery($query)
  184.     {
  185.         $ismanip = DB::isManip($query);
  186.         $this->last_query = $query;
  187.         $query = $this->_modifyQuery($query);
  188.         ini_set('track_errors', true);
  189.         $result = @sqlite_query($query, $this->connection);
  190.         ini_restore('track_errors');
  191.         $this->_lasterror = isset($php_errormsg) ? $php_errormsg : '';
  192.         $this->result = $result;
  193.         if (!$this->result) {
  194.             return $this->sqliteRaiseError(null);
  195.         }
  196.  
  197.         /* sqlite_query() seems to allways return a resource */
  198.         /* so cant use that. Using $ismanip instead          */
  199.         if (!$ismanip) {
  200.             $numRows = $this->numRows($result);
  201.  
  202.             /* if numRows() returned PEAR_Error */
  203.             if (is_object($numRows)) {
  204.                 return $numRows;
  205.             }
  206.             return $result;
  207.         }
  208.         return DB_OK;
  209.     }
  210.  
  211.     // }}}
  212.     // {{{ nextResult()
  213.  
  214.     /**
  215.      * Move the internal sqlite result pointer to the next available result.
  216.      *
  217.      * @param a valid sqlite result resource
  218.      * @access public
  219.      * @return true if a result is available otherwise return false
  220.      */
  221.     function nextResult($result)
  222.     {
  223.         return false;
  224.     }
  225.  
  226.     // }}}
  227.     // {{{ fetchInto()
  228.  
  229.     /**
  230.      * Fetch a row and insert the data into an existing array.
  231.      *
  232.      * Formating of the array and the data therein are configurable.
  233.      * See DB_result::fetchInto() for more information.
  234.      *
  235.      * @param resource $result    query result identifier
  236.      * @param array    $arr       (reference) array where data from the row
  237.      *                            should be placed
  238.      * @param int      $fetchmode how the resulting array should be indexed
  239.      * @param int      $rownum    the row number to fetch
  240.      *
  241.      * @return mixed DB_OK on success, null when end of result set is
  242.      *               reached or on failure
  243.      *
  244.      * @see DB_result::fetchInto()
  245.      * @access private
  246.      */
  247.     function fetchInto($result, &$arr, $fetchmode, $rownum=null)
  248.     {
  249.         if ($rownum !== null) {
  250.             if (!@sqlite_seek($this->result, $rownum)) {
  251.                 return null;
  252.             }
  253.         }
  254.         if ($fetchmode & DB_FETCHMODE_ASSOC) {
  255.             $arr = @sqlite_fetch_array($result, SQLITE_ASSOC);
  256.             if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) {
  257.                 $arr = array_change_key_case($arr, CASE_LOWER);
  258.             }
  259.         } else {
  260.             $arr = @sqlite_fetch_array($result, SQLITE_NUM);
  261.         }
  262.         if (!$arr) {
  263.             /* See: http://bugs.php.net/bug.php?id=22328 */
  264.             return null;
  265.         }
  266.         if ($this->options['portability'] & DB_PORTABILITY_RTRIM) {
  267.             /*
  268.              * Even though this DBMS already trims output, we do this because
  269.              * a field might have intentional whitespace at the end that
  270.              * gets removed by DB_PORTABILITY_RTRIM under another driver.
  271.              */
  272.             $this->_rtrimArrayValues($arr);
  273.         }
  274.         if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) {
  275.             $this->_convertNullArrayValuesToEmpty($arr);
  276.         }
  277.         return DB_OK;
  278.     }
  279.  
  280.     // }}}
  281.     // {{{ freeResult()
  282.  
  283.     /**
  284.      * Free the internal resources associated with $result.
  285.      *
  286.      * @param $result SQLite result identifier
  287.      * @access public
  288.      * @return bool true on success, false if $result is invalid
  289.      */
  290.     function freeResult(&$result)
  291.     {
  292.         // XXX No native free?
  293.         if (!is_resource($result)) {
  294.             return false;
  295.         }
  296.         $result = null;
  297.         return true;
  298.     }
  299.  
  300.     // }}}
  301.     // {{{ numCols()
  302.  
  303.     /**
  304.      * Gets the number of columns in a result set.
  305.      *
  306.      * @return number of columns in a result set
  307.      */
  308.     function numCols($result)
  309.     {
  310.         $cols = @sqlite_num_fields($result);
  311.         if (!$cols) {
  312.             return $this->sqliteRaiseError();
  313.         }
  314.         return $cols;
  315.     }
  316.  
  317.     // }}}
  318.     // {{{ numRows()
  319.  
  320.     /**
  321.      * Gets the number of rows affected by a query.
  322.      *
  323.      * @return number of rows affected by the last query
  324.      */
  325.     function numRows($result)
  326.     {
  327.         $rows = @sqlite_num_rows($result);
  328.         if (!is_integer($rows)) {
  329.             return $this->raiseError();
  330.         }
  331.         return $rows;
  332.     }
  333.  
  334.     // }}}
  335.     // {{{ affected()
  336.  
  337.     /**
  338.      * Gets the number of rows affected by a query.
  339.      *
  340.      * @return number of rows affected by the last query
  341.      */
  342.     function affectedRows()
  343.     {
  344.         return @sqlite_changes($this->connection);
  345.     }
  346.  
  347.     // }}}
  348.     // {{{ errorNative()
  349.  
  350.     /**
  351.      * Get the native error string of the last error (if any) that
  352.      * occured on the current connection.
  353.      *
  354.      * This is used to retrieve more meaningfull error messages DB_pgsql
  355.      * way since sqlite_last_error() does not provide adequate info.
  356.      *
  357.      * @return string native SQLite error message
  358.      */
  359.     function errorNative()
  360.     {
  361.         return($this->_lasterror);
  362.     }
  363.  
  364.     // }}}
  365.     // {{{ errorCode()
  366.  
  367.     /**
  368.      * Determine PEAR::DB error code from the database's text error message.
  369.      *
  370.      * @param  string  $errormsg  error message returned from the database
  371.      * @return integer  an error number from a DB error constant
  372.      */
  373.     function errorCode($errormsg)
  374.     {
  375.         static $error_regexps;
  376.         if (!isset($error_regexps)) {
  377.             $error_regexps = array(
  378.                 '/^no such table:/' => DB_ERROR_NOSUCHTABLE,
  379.                 '/^table .* already exists$/' => DB_ERROR_ALREADY_EXISTS,
  380.                 '/PRIMARY KEY must be unique/i' => DB_ERROR_CONSTRAINT,
  381.                 '/is not unique/' => DB_ERROR_CONSTRAINT,
  382.                 '/uniqueness constraint failed/' => DB_ERROR_CONSTRAINT,
  383.                 '/may not be NULL/' => DB_ERROR_CONSTRAINT_NOT_NULL,
  384.                 '/^no such column:/' => DB_ERROR_NOSUCHFIELD,
  385.                 '/^near ".*": syntax error$/' => DB_ERROR_SYNTAX
  386.             );
  387.         }
  388.         foreach ($error_regexps as $regexp => $code) {
  389.             if (preg_match($regexp, $errormsg)) {
  390.                 return $code;
  391.             }
  392.         }
  393.         // Fall back to DB_ERROR if there was no mapping.
  394.         return DB_ERROR;
  395.     }
  396.  
  397.     // }}}
  398.     // {{{ dropSequence()
  399.  
  400.     /**
  401.      * Deletes a sequence
  402.      *
  403.      * @param string $seq_name  name of the sequence to be deleted
  404.      *
  405.      * @return int  DB_OK on success.  DB_Error if problems.
  406.      *
  407.      * @internal
  408.      * @see DB_common::dropSequence()
  409.      * @access public
  410.      */
  411.     function dropSequence($seq_name)
  412.     {
  413.         $seqname = $this->getSequenceName($seq_name);
  414.         return $this->query("DROP TABLE $seqname");
  415.     }
  416.  
  417.     /**
  418.      * Creates a new sequence
  419.      *
  420.      * @param string $seq_name  name of the new sequence
  421.      *
  422.      * @return int  DB_OK on success.  A DB_Error object is returned if
  423.      *              problems arise.
  424.      *
  425.      * @internal
  426.      * @see DB_common::createSequence()
  427.      * @access public
  428.      */
  429.     function createSequence($seq_name)
  430.     {
  431.         $seqname = $this->getSequenceName($seq_name);
  432.         $query   = 'CREATE TABLE ' . $seqname .
  433.                    ' (id INTEGER UNSIGNED PRIMARY KEY) ';
  434.         $result  = $this->query($query);
  435.         if (DB::isError($result)) {
  436.             return($result);
  437.         }
  438.         $query   = "CREATE TRIGGER ${seqname}_cleanup AFTER INSERT ON $seqname
  439.                     BEGIN
  440.                         DELETE FROM $seqname WHERE id<LAST_INSERT_ROWID();
  441.                     END ";
  442.         $result  = $this->query($query);
  443.         if (DB::isError($result)) {
  444.             return($result);
  445.         }
  446.     }
  447.  
  448.     // }}}
  449.     // {{{ nextId()
  450.  
  451.     /**
  452.      * Returns the next free id in a sequence
  453.      *
  454.      * @param string  $seq_name  name of the sequence
  455.      * @param boolean $ondemand  when true, the seqence is automatically
  456.      *                           created if it does not exist
  457.      *
  458.      * @return int  the next id number in the sequence.  DB_Error if problem.
  459.      *
  460.      * @internal
  461.      * @see DB_common::nextID()
  462.      * @access public
  463.      */
  464.     function nextId($seq_name, $ondemand = true)
  465.     {
  466.         $seqname = $this->getSequenceName($seq_name);
  467.  
  468.         do {
  469.             $repeat = 0;
  470.             $this->pushErrorHandling(PEAR_ERROR_RETURN);
  471.             $result = $this->query("INSERT INTO $seqname (id) VALUES (NULL)");
  472.             $this->popErrorHandling();
  473.             if ($result === DB_OK) {
  474.                 $id = @sqlite_last_insert_rowid($this->connection);
  475.                 if ($id != 0) {
  476.                     return $id;
  477.                 }
  478.             } elseif ($ondemand && DB::isError($result) &&
  479.                       $result->getCode() == DB_ERROR_NOSUCHTABLE)
  480.             {
  481.                 $result = $this->createSequence($seq_name);
  482.                 if (DB::isError($result)) {
  483.                     return $this->raiseError($result);
  484.                 } else {
  485.                     $repeat = 1;
  486.                 }
  487.             }
  488.         } while ($repeat);
  489.  
  490.         return $this->raiseError($result);
  491.     }
  492.  
  493.     // }}}
  494.     // {{{ getSpecialQuery()
  495.  
  496.     /**
  497.      * Returns the query needed to get some backend info.
  498.      *
  499.      * Refer to the online manual at http://sqlite.org/sqlite.html.
  500.      *
  501.      * @param string $type What kind of info you want to retrieve
  502.      * @return string The SQL query string
  503.      */
  504.     function getSpecialQuery($type, $args=array())
  505.     {
  506.         if (!is_array($args))
  507.             return $this->raiseError('no key specified', null, null, null,
  508.                                      'Argument has to be an array.');
  509.         switch (strtolower($type)) {
  510.             case 'master':
  511.                 return 'SELECT * FROM sqlite_master;';
  512.             case 'tables':
  513.                 return "SELECT name FROM sqlite_master WHERE type='table' "
  514.                        . 'UNION ALL SELECT name FROM sqlite_temp_master '
  515.                        . "WHERE type='table' ORDER BY name;";
  516.             case 'schema':
  517.                 return 'SELECT sql FROM (SELECT * FROM sqlite_master UNION ALL '
  518.                        . 'SELECT * FROM sqlite_temp_master) '
  519.                        . "WHERE type!='meta' ORDER BY tbl_name, type DESC, name;";
  520.             case 'schemax':
  521.             case 'schema_x':
  522.                 /*
  523.                  * Use like:
  524.                  * $res = $db->query($db->getSpecialQuery('schema_x', array('table' => 'table3')));
  525.                  */
  526.                 return 'SELECT sql FROM (SELECT * FROM sqlite_master UNION ALL '
  527.                        . 'SELECT * FROM sqlite_temp_master) '
  528.                        . "WHERE tbl_name LIKE '{$args['table']}' AND type!='meta' "
  529.                        . 'ORDER BY type DESC, name;';
  530.             case 'alter':
  531.                 /*
  532.                  * SQLite does not support ALTER TABLE; this is a helper query
  533.                  * to handle this. 'table' represents the table name, 'rows'
  534.                  * the news rows to create, 'save' the row(s) to keep _with_
  535.                  * the data.
  536.                  *
  537.                  * Use like:
  538.                  * $args = array(
  539.                  *     'table' => $table,
  540.                  *     'rows'  => "id INTEGER PRIMARY KEY, firstname TEXT, surname TEXT, datetime TEXT",
  541.                  *     'save'  => "NULL, titel, content, datetime"
  542.                  * );
  543.                  * $res = $db->query( $db->getSpecialQuery('alter', $args));
  544.                  */
  545.                 $rows = strtr($args['rows'], $this->keywords);
  546.  
  547.                 $q = array(
  548.                     'BEGIN TRANSACTION',
  549.                     "CREATE TEMPORARY TABLE {$args['table']}_backup ({$args['rows']})",
  550.                     "INSERT INTO {$args['table']}_backup SELECT {$args['save']} FROM {$args['table']}",
  551.                     "DROP TABLE {$args['table']}",
  552.                     "CREATE TABLE {$args['table']} ({$args['rows']})",
  553.                     "INSERT INTO {$args['table']} SELECT {$rows} FROM {$args['table']}_backup",
  554.                     "DROP TABLE {$args['table']}_backup",
  555.                     'COMMIT',
  556.                 );
  557.  
  558.                 // This is a dirty hack, since the above query will no get executed with a single
  559.                 // query call; so here the query method will be called directly and return a select instead.
  560.                 foreach ($q as $query) {
  561.                     $this->query($query);
  562.                 }
  563.                 return "SELECT * FROM {$args['table']};";
  564.             default:
  565.                 return null;
  566.         }
  567.     }
  568.  
  569.     // }}}
  570.     // {{{ getDbFileStats()
  571.  
  572.     /**
  573.      * Get the file stats for the current database.
  574.      *
  575.      * Possible arguments are dev, ino, mode, nlink, uid, gid, rdev, size,
  576.      * atime, mtime, ctime, blksize, blocks or a numeric key between
  577.      * 0 and 12.
  578.      *
  579.      * @param string $arg Array key for stats()
  580.      * @return mixed array on an unspecified key, integer on a passed arg and
  581.      * false at a stats error.
  582.      */
  583.     function getDbFileStats($arg = '')
  584.     {
  585.         $stats = stat($this->dsn['database']);
  586.         if ($stats == false) {
  587.             return false;
  588.         }
  589.         if (is_array($stats)) {
  590.             if (is_numeric($arg)) {
  591.                 if (((int)$arg <= 12) & ((int)$arg >= 0)) {
  592.                     return false;
  593.                 }
  594.                 return $stats[$arg ];
  595.             }
  596.             if (array_key_exists(trim($arg), $stats)) {
  597.                 return $stats[$arg ];
  598.             }
  599.         }
  600.         return $stats;
  601.     }
  602.  
  603.     // }}}
  604.     // {{{ escapeSimple()
  605.  
  606.     /**
  607.      * Escape a string according to the current DBMS's standards
  608.      *
  609.      * In SQLite, this makes things safe for inserts/updates, but may
  610.      * cause problems when performing text comparisons against columns
  611.      * containing binary data. See the
  612.      * {@link http://php.net/sqlite_escape_string PHP manual} for more info.
  613.      *
  614.      * @param string $str  the string to be escaped
  615.      *
  616.      * @return string  the escaped string
  617.      *
  618.      * @since 1.6.1
  619.      * @see DB_common::escapeSimple()
  620.      * @internal
  621.      */
  622.     function escapeSimple($str) {
  623.         return @sqlite_escape_string($str);
  624.     }
  625.  
  626.     // }}}
  627.     // {{{ modifyLimitQuery()
  628.  
  629.     function modifyLimitQuery($query, $from, $count, $params = array())
  630.     {
  631.         $query = $query . " LIMIT $count OFFSET $from";
  632.         return $query;
  633.     }
  634.  
  635.     // }}}
  636.     // {{{ modifyQuery()
  637.  
  638.     /**
  639.      * "DELETE FROM table" gives 0 affected rows in SQLite.
  640.      *
  641.      * This little hack lets you know how many rows were deleted.
  642.      *
  643.      * @param string $query The SQL query string
  644.      * @return string The SQL query string
  645.      */
  646.     function _modifyQuery($query)
  647.     {
  648.         if ($this->options['portability'] & DB_PORTABILITY_DELETE_COUNT) {
  649.             if (preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $query)) {
  650.                 $query = preg_replace('/^\s*DELETE\s+FROM\s+(\S+)\s*$/',
  651.                                       'DELETE FROM \1 WHERE 1=1', $query);
  652.             }
  653.         }
  654.         return $query;
  655.     }
  656.  
  657.     // }}}
  658.     // {{{ sqliteRaiseError()
  659.  
  660.     /**
  661.      * Gather information about an error, then use that info to create a
  662.      * DB error object and finally return that object.
  663.      *
  664.      * @param  integer  $errno  PEAR error number (usually a DB constant) if
  665.      *                          manually raising an error
  666.      * @return object  DB error object
  667.      * @see errorNative()
  668.      * @see errorCode()
  669.      * @see DB_common::raiseError()
  670.      */
  671.     function sqliteRaiseError($errno = null)
  672.     {
  673.  
  674.         $native = $this->errorNative();
  675.         if ($errno === null) {
  676.             $errno = $this->errorCode($native);
  677.         }
  678.  
  679.         $errorcode = @sqlite_last_error($this->connection);
  680.         $userinfo = "$errorcode ** $this->last_query";
  681.  
  682.         return $this->raiseError($errno, null, null, $userinfo, $native);
  683.     }
  684.  
  685.     // }}}
  686. }
  687.  
  688. /*
  689.  * Local variables:
  690.  * tab-width: 4
  691.  * c-basic-offset: 4
  692.  * End:
  693.  */
  694.  
  695. ?>
  696.